<?php

/**
 * 新版本,每个咨询类型. 单独定价.
 */

namespace app\v6\controller;

use think\Db;
use think\Exception;
use think\facade\Env;
// 接入支付
use think\facade\Log;
use think\facade\Lang;
use Yurun\PaySDK\Weixin\JSAPI\Params\JSParams\Request as jsRequest;
use Yurun\PaySDK\Weixin\JSAPI\Params\Pay\Request;
use Yurun\PaySDK\Weixin\Params\PublicParams;
use Yurun\PaySDK\Weixin\SDK;

class Combo
{
    /**
     * 获取用户套餐.
     */
    public function getUserCombo()
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];

        try {
            $id = getUserId();
            // 入单请求参数(并且不是邮箱)
            $mField = 'once_nums,month_time,works_once_nums,works_month_time,medical_once_nums,medical_month_time,emotion_once_nums,emotion_month_nums,free_nums,pr_once_nums,pr_month_time,group_once_nums,group_month_time,stu_once_nums,stu_month_time,physical_once_mums,physical_month_time,symptom_inquiry_once_mums,symptom_inquiry_month_time';
            $userComboInfo = Db::name('member')->field($mField)->where('id', $id)->find();
            // 获取 单次/月卡的费用
            $comboInfo = Db::name('combos')->field('combo_type,fee')->select();
            $res['code'] = 0;

            $res['data']['free_nums'] = $userComboInfo['free_nums'];
            // 项目预测(7)
            $res['data']['once_nums'] = isset($userComboInfo['once_nums']) ? $userComboInfo['once_nums'] : 0;
            $res['data']['month_day'] = isset($userComboInfo['month_time']) ? endDate($userComboInfo['month_time']) : 0;
            // 项目预测, 单次和月卡费用
            $res['data']['oncepay'] = isset($comboInfo[0]['fee']) ? $comboInfo[0]['fee'] : 0;
            $res['data']['monpay'] = isset($comboInfo[1]['fee']) ? $comboInfo[1]['fee'] : 0;

            // 工作事业(8)
            $res['data']['works_once_nums'] = isset($userComboInfo['works_once_nums']) ? $userComboInfo['works_once_nums'] : 0;
            $res['data']['works_month_nums'] = isset($userComboInfo['works_month_time']) ? endDate($userComboInfo['works_month_time']) : 0;
            // 工作事业, 单次和月卡费用
            $res['data']['works_oncepay'] = isset($comboInfo[2]['fee']) ? $comboInfo[2]['fee'] : 0;
            $res['data']['works_monpay'] = isset($comboInfo[3]['fee']) ? $comboInfo[3]['fee'] : 0;

            // 情感咨询(9)
            $res['data']['emotion_once_nums'] = isset($userComboInfo['emotion_once_nums']) ? $userComboInfo['emotion_once_nums'] : 0;
            $res['data']['emotion_month_nums'] = isset($userComboInfo['emotion_month_time']) ? endDate($userComboInfo['emotion_month_time']) : 0;
            // 情感咨询, 单次和月卡费用
            $res['data']['emotion_oncepay'] = isset($comboInfo[4]['fee']) ? $comboInfo[4]['fee'] : 0;
            $res['data']['emotion_monpay'] = isset($comboInfo[5]['fee']) ? $comboInfo[5]['fee'] : 0;

            // 公关审核(10)
            $res['data']['pr_once_nums'] = isset($userComboInfo['pr_once_nums']) ? $userComboInfo['pr_once_nums'] : 0;
            $res['data']['pr_month_nums'] = isset($userComboInfo['pr_month_time']) ? endDate($userComboInfo['pr_month_time']) : 0;
            // 公关审核, 单次和月卡费用
            $res['data']['pr_oncepay'] = isset($comboInfo[6]['fee']) ? $comboInfo[6]['fee'] : 0;
            $res['data']['pr_monpay'] = isset($comboInfo[7]['fee']) ? $comboInfo[7]['fee'] : 0;

            // 团体套餐(11,12,13,14,15,16,17)
            $res['data']['group_once_nums'] = isset($userComboInfo['group_once_nums']) ? $userComboInfo['group_once_nums'] : 0;
            $res['data']['group_month_nums'] = isset($userComboInfo['group_month_time']) ? endDate($userComboInfo['group_month_time']) : 0;
            // 团体套餐, 单次和月卡费用
            $res['data']['group_oncepay'] = isset($comboInfo[8]['fee']) ? $comboInfo[8]['fee'] : 0;
            $res['data']['group_monpay'] = isset($comboInfo[9]['fee']) ? $comboInfo[9]['fee'] : 0;

            // 健康评测
            $res['data']['medical_once_nums'] = isset($userComboInfo['medical_once_nums']) ? $userComboInfo['medical_once_nums'] : 0;
            $res['data']['medical_month_nums'] = isset($userComboInfo['medical_month_time']) ? endDate($userComboInfo['medical_month_time']) : 0;
            //学业事业 （20）
            $res['data']['stu_once_pay'] = isset($comboInfo[14]['fee']) ? $comboInfo[14]['fee'] : 0;
            $res['data']['stu_month_pay'] = isset($comboInfo[15]['fee']) ? $comboInfo[15]['fee'] : 0;
            $res['data']['stu_once_nums'] = isset($userComboInfo['stu_once_nums']) ? $userComboInfo['stu_once_nums'] : 0;
            $res['data']['stu_month_nums'] = isset($userComboInfo['stu_month_time']) && !empty($userComboInfo['stu_month_time']) ? endDate($userComboInfo['stu_month_time']) : 0;

            $res['data']['medical_once_pay'] = isset($comboInfo[18]['fee']) ? $comboInfo[18]['fee'] : 0;
            $res['data']['medical_month_pay'] = isset($comboInfo[19]['fee']) ? $comboInfo[19]['fee'] : 0;


            // 体质查询---次卡
            $res['data']['tizhi_once_nums'] = isset($comboInfo[16]['fee']) ? $comboInfo[16]['fee'] : 0;
            // 体质查询---次卡剩余次数
            $res['data']['tizhi_once'] = isset($userComboInfo['physical_once_mums']) ? $userComboInfo['physical_once_mums'] : 0;
            // 体质查询---月卡价格
            $res['data']['tizhi_month_pay'] = isset($comboInfo[17]['fee']) ? $comboInfo[17]['fee'] : 0;
            // 体质查询---月卡剩余天数
            $res['data']['tizhi_month_nums'] = isset($userComboInfo['physical_month_time']) ? endDate($userComboInfo['physical_month_time']) : 0;

            //中医诊断---次卡价格
            $res['data']['zhongyao_once_nums'] = isset($comboInfo[18]['fee']) ? $comboInfo[18]['fee'] : 0;
            //中医诊断---次卡剩余次数
            $res['data']['symptom_inquiry_once_mums'] = isset($userComboInfo['symptom_inquiry_once_mums']) ? $userComboInfo['symptom_inquiry_once_mums'] : 0;
            //中医诊断---月卡价格
            $res['data']['zhongyao_month_pay'] = isset($comboInfo[19]['fee']) ? $comboInfo[19]['fee'] : 0;
            //中医诊断---月卡剩余天数
            $res['data']['symptom_inquiry_month_nums'] = isset($userComboInfo['symptom_inquiry_month_time']) ? endDate($userComboInfo['symptom_inquiry_month_time']) : 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        } catch (Exception $e) {
            $res['msg'] = $e->getMessage();
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * 最新版本AI预测.
     */
    public function v3latestPersonPredict()
    {
        $params = input('');
        // 需要展示时间节点预测. personal_consult_show
        $personConsultShow = config('personal_consult_show');
        $personConf = config('personal_consult_tmpl');
        // 大类型
        $type = isset($params['types']) ? $params['types'] : 0;
        // 大栏目下的 子菜单
        $itypes = isset($params['itypes']) ? $params['itypes'] : 0;
        // 用户填写的信息
        $personMsg = isset($params['person_fix_msg']) ? $params['person_fix_msg'] : '';
        // 职位. 该字段 仅在工作事业栏目有
        $jobTitle = isset($params['person_job']) ? $params['person_job'] : '';
        // 该参数指的是, 当前咨询对应 的 结果ID
        $id = isset($params['id']) ? $params['id'] : 0;
        $res = ['code' => 0, 'data' => [], 'msg' => ''];

        if (empty($type) && empty($id)) {
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }

        // 没有ID的情况,根据type取出随机数
        if (empty($id)) {
            // 查询当前用户, 在当前类型下,是否有可用套餐

            // 用户无可用套餐, 不允许咨询
            $memField = 'id,once_nums,month_day,works_once_nums,works_month_nums,emotion_once_nums,emotion_month_nums,pr_once_nums,pr_month_nums';
            $userComboInfo = Db::name('member')->field($memField)->where(['phone' => $params['user_phone']])->find();
            // 根据每个咨询
            switch ($type) {
                case 1:
                    if ($userComboInfo['once_nums'] <= 0 && $userComboInfo['month_day'] <= 0) {
                        $res['code'] = 1;
                        $res['msg'] = Lang::get('project_no_combo');
                        exit(json_encode($res, JSON_UNESCAPED_UNICODE));
                        exit;
                    }
                    break;
                case 2:
                    if ($userComboInfo['works_once_nums'] <= 0 && $userComboInfo['works_month_nums'] <= 0) {
                        $res['code'] = 1;
                        $res['msg'] = Lang::get('career_no_combo');
                        exit(json_encode($res, JSON_UNESCAPED_UNICODE));
                        exit;
                    }
                    break;
                case 3:
                    if ($userComboInfo['emotion_once_nums'] <= 0 && $userComboInfo['emotion_month_nums'] <= 0) {
                        $res['code'] = 1;
                        $res['msg'] = Lang::get('emotion_no_combo');
                        exit(json_encode($res, JSON_UNESCAPED_UNICODE));
                        exit;
                    }
                    break;
                case 4:
                    if ($userComboInfo['pr_once_nums'] <= 0 && $userComboInfo['pr_month_nums'] <= 0) {
                        $res['code'] = 1;
                        $res['msg'] = Lang::get('pr_no_combo');
                        exit(json_encode($res, JSON_UNESCAPED_UNICODE));
                        exit;
                    }
                    break;
            }

            // 根据 大小菜单, 确认用户提问信息
            $personTpl = isset($personConf[$type]['items'][$itypes]) ? $personConf[$type]['items'][$itypes] : '';

            // 如果是 工作事业选择
            if ($itypes == 4) {
                $personTpl = sprintf($personTpl, $jobTitle, $personMsg);
            }
            // 非工作事业选择
            if ($itypes != 4) {
                $personTpl = sprintf($personTpl, $personMsg);
            }

            // 类型不能为空
            if (empty($type)) {
                $res['code'] = 0;
                $res['msg'] = Lang::get('consultation_type_required');
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
                exit;
            }

            // 新增字段
            $loginUserId = getUserId();
            if (empty($loginUserId)) {
                $res['code'] = 0;
                $res['msg'] = Lang::get('user_not_logged_in');
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
                exit;
            }
            $historyIdentifier = (string) $loginUserId;
            // 随机取一个. 如果是: 项目预测: 1 + 公关审核
            if ($type == 1 || $type == 4) {
                $typeIds = Db::name('docs_latest')->field('id')->select();
            }
            // 随机取一个. 如果是: 工作事业选择: 2
            if ($type == 2) {
                $typeIds = Db::name('docs_works')->field('id')->select();
            }
            // 随机取一个. 如果是: 情感咨询选择: 3
            if ($type == 3) {
                $typeIds = Db::name('docs_emotion')->field('id')->select();
            }

            $typeIdsArr = array_column($typeIds, 'id');
            // 从数组里面随机取出一个
            $key = array_rand($typeIdsArr);
            $id = $typeIdsArr[$key];

            $info = [];
            if ($type == 1 || $type == 4) {
                $info = Db::name('docs_latest')->field('*')->where(['id' => $id])->find();
            }
            // 随机取一个. 如果是: 工作事业选择: 2
            if ($type == 2) {
                $info = Db::name('docs_works')->field('*')->where(['id' => $id])->find();
            }
            // 随机取一个. 如果是: 情感咨询选择: 3
            if ($type == 3) {
                $info = Db::name('docs_emotion')->field('*')->where(['id' => $id])->find();
            }
            // 将当前用户的, 提交记录 存储
            $isShowTimes = in_array($itypes, $personConsultShow['is_show_time_ids']) ? 1 : 0;

            $insertData = [
                'result_id' => $id,
                'user_phone' => $historyIdentifier,
                'person_menu_id' => $type,
                'person_menu_item_id' => $itypes,
                'person_fix_msg' => $personMsg,
                'person_job' => $jobTitle,
                'is_show_time_res' => $isShowTimes,
                'add_time' => date('Y-m-d H:i:s', time()),
            ];
            $historyId = Db::name('new_user_question_history')->insertGetId($insertData);

            $info['is_show_time_res'] = $isShowTimes;
            $info['person_tpl'] = $personTpl;
            $info['history_id'] = $historyId;
            $info['types'] = $type;
            $info['itypes'] = $itypes;
            // 循环数据里面的 每个 value.替换 \n为 <br/>
            if (!empty($info)) {
                foreach ($info as $kItem => $kVal) {
                    $info[$kItem] = str_replace('\n', '<br/>', $info[$kItem]);
                }
            }
            $res['data'] = $info;
            // TODO: 传入combo_type
            $comboType = isset($params['comboType']) ? $params['comboType'] : 100;
            // 无月卡套餐, 扣减次数.有月卡继续执行
            switch ($type) {
                case 1:
                    if ($userComboInfo['month_day'] <= 0) {
                        // 用户表扣减次数
                        Db::name('member')->where(['phone' => $params['user_phone']])->setDec('once_nums');
                    }
                    break;
                case 2:
                    if ($userComboInfo['works_month_nums'] <= 0) {
                        // 用户表扣减次数
                        Db::name('member')->where(['phone' => $params['user_phone']])->setDec('works_once_nums');
                    }
                    break;
                case 3:
                    if ($userComboInfo['emotion_month_nums'] <= 0) {
                        // 用户表扣减次数
                        Db::name('member')->where(['phone' => $params['user_phone']])->setDec('emotion_once_nums');
                    }
                    break;
                case 4:
                    if ($userComboInfo['pr_month_nums'] <= 0) {
                        // 用户表扣减次数
                        Db::name('member')->where(['phone' => $params['user_phone']])->setDec('pr_once_nums');
                    }
                    break;
            }
            // Log::info('提问记录::'. json_encode($insertData, JSON_UNESCAPED_UNICODE));

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        } else {
            // 个人 咨询,历史记录
            $historyId = isset($params['history_id']) ? $params['history_id'] : 0;

            if (empty($historyId)) {
                $res['msg'] = '咨询记录ID不能为空!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 根据 $historyId, 得出它咨询所 得到的答案ID
            $historyInfo = Db::name('new_user_question_history')->field('person_fix_msg,person_job,result_id')->where(['id' => $historyId])->find();

            $resultId = $id;
            // $resultId = isset($historyInfo['result_id']) ? $historyInfo['result_id'] : 0;

            if (empty($resultId)) {
                $res['msg'] = '未查询到咨询结果!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 根据 大小菜单, 确认用户提问信息
            $personTpl = isset($personConf[$type]['items'][$itypes]) ? $personConf[$type]['items'][$itypes] : '';
            // 如果是 工作事业选择
            if ($itypes == 4) {
                $personTpl = sprintf($personTpl, $historyInfo['person_fix_msg'], $historyInfo['person_job']);
            }
            // 非工作事业选择
            if ($itypes != 4) {
                $personTpl = sprintf($personTpl, $historyInfo['person_fix_msg']);
            }

            // 随机取一个. 如果是: 项目预测: 1 + 公关审核
            if ($type == 1 || $type == 4) {
                $info = Db::name('docs_latest')->field('*')->where(['id' => $resultId])->find();
            }
            // 随机取一个. 如果是: 工作事业选择: 2
            if ($type == 2) {
                $info = Db::name('docs_works')->field('*')->where(['id' => $resultId])->find();
            }
            // 随机取一个. 如果是: 情感咨询选择: 3
            if ($type == 3) {
                $info = Db::name('docs_emotion')->field('*')->where(['id' => $resultId])->find();
            }

            $info['is_show_time_res'] = 1;
            $info['person_tpl'] = $personTpl;
            $res['code'] = 0;
            // 循环数据里面的 每个 value.替换 \n为 <br/>
            if (!empty($info)) {
                foreach ($info as $kItem => $kVal) {
                    $info[$kItem] = str_replace('\n', '<br/>', $info[$kItem]);
                }
            }

            // if (isset($info['twenty_years_predict']))   $info['twenty_years_predict'] = str_replace('\n', '<br/>', $info['twenty_years_predict']);
            $res['data'] = $info;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        exit;
    }

    /**
     * 获取当前用户 是否可以使用 咨询.
     */
    public function v2getUserIsUse()
    {
        $params = input('');
        $res = ['code' => 1, 'data' => [], 'msg' => ''];

        if (empty($params['user_phone'])) {
            $res['msg'] = '用户唯一凭证为必传标识';
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        // 1-项目咨询,2-工作事业,3-情感咨询,4-公关审核
        $allowTypes = [1, 2, 3, 4];
        // 套餐类型, 为必传参数
        if (empty($params['type']) || !in_array($params['type'], $allowTypes)) {
            $res['msg'] = '套餐类型为必传参数';
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        $type = $params['type'];
        // 获取单次付费标准
        $comboVal = [0];
        if ($type == 1) {
            $comboVal = Db::name('combos')->where(['combo_type' => 1])->column('fee');
        }
        if ($type == 2) {
            $comboVal = Db::name('combos')->where(['combo_type' => 3])->column('fee');
        }
        if ($type == 3) {
            $comboVal = Db::name('combos')->where(['combo_type' => 5])->column('fee');
        }
        if ($type == 4) {
            $comboVal = Db::name('combos')->where(['combo_type' => 7])->column('fee');
        }
        if ($type == 5) {
            $comboVal = Db::name('combos')->where(['combo_type' => 9])->column('fee');
        }

        $res['data']['zifei'] = isset($comboVal[0]) ? $comboVal[0] : 0;
        $res['data']['times'] = 1;

        // 获取用户是有当前类型的套餐
        $mField = 'once_nums,month_day,works_once_nums,works_month_nums,emotion_once_nums,emotion_month_nums,pr_once_nums,pr_month_nums,medical_month_nums';
        $memInfo = Db::name('member')->field($mField)->where(['phone' => $params['user_phone']])->find();

        if (empty($memInfo)) {
            $res['code'] = 0;
            $res['data']['is_used'] = 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        // 根据用户的 咨询类型. 获取是否有咨询次数
        if ($type == 1 && $memInfo['once_nums'] < 1 && $memInfo['month_day'] < 1) {
            $res['code'] = 0;
            $res['data']['is_used'] = 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        // 查询工作事业
        if ($type == 2 && $memInfo['works_once_nums'] < 1 && $memInfo['works_month_nums'] < 1) {
            $res['code'] = 0;
            $res['data']['is_used'] = 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        // 查询情感咨询
        if ($type == 3 && $memInfo['emotion_once_nums'] < 1 && $memInfo['emotion_month_nums'] < 1) {
            $res['code'] = 0;
            $res['data']['is_used'] = 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        // 查询公关审核
        if ($type == 4 && $memInfo['pr_once_nums'] < 1 && $memInfo['pr_month_nums'] < 1) {
            $res['code'] = 0;
            $res['data']['is_used'] = 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        // 查询健康评估
        if ($type == 5 && $memInfo['medical_month_nums'] < 1) {
            $res['code'] = 0;
            $res['data']['is_used'] = 0;

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }

        // 只有有一种场景, 都可以满足
        $res['code'] = 0;
        $res['data']['is_used'] = 1;
        exit(json_encode($res, JSON_UNESCAPED_UNICODE));
    }

    /**
     * 单次付费咨询.
     */
    public function oncePay()
    {
        $res = ['code' => 0, 'data' => [], 'msg' => ''];
        try {
            $reqParams = input('');

            // 入单请求参数
            if (empty($reqParams['user_phone'])) {
                $res['msg'] = '用户唯一凭证为必传标识';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }

            $comboType = isset($reqParams['combo_type']) ? $reqParams['combo_type'] : -1;
            $types = isset($reqParams['type']) ? $reqParams['type'] : -1;

            // 咨询类型. 总共分4个类型. TODO: 可使用数据库 管理
            $allowTypes = [1, 2, 3, 4, 5, 6];
            if (!in_array($types, $allowTypes)) {
                $res['msg'] = '咨询类型为必传!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 套餐类型: 0-单次咨询,1-包月套餐
            $comboTypeArr = [0, 1];

            if (!in_array($comboType, $comboTypeArr)) {
                $res['msg'] = '套餐标识错误';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 获取当前类型下, 每个套餐的数据表信息
            $miniComboConf = config('app.mini_combo');
            $tempTblComboType = $miniComboConf[$types][$comboType];

            if (empty($tempTblComboType)) {
                $res['msg'] = '套餐匹配失败!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 获取用户openid
            $mField = 'openid,once_nums,month_day,works_once_nums,works_month_nums,emotion_once_nums,emotion_month_nums,pr_once_nums,pr_month_nums,group_once_nums,group_month_nums,stu_once_nums,stu_month_nums';
            $memInfo = Db::name('member')->field($mField)->where(['phone' => $reqParams['user_phone']])->find();
            $openid = isset($memInfo['openid']) ? $memInfo['openid'] : '';

            if (empty($openid)) {
                $res['msg'] = '微信用户标识错误';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }

            $amount = $comboVal[0];
            $content = '天纪云-咨询服务费';
            $paymentSn = 'AI_'.date('YmdHis').'_'.mt_rand(10000, 99999);

            $params = new PublicParams();
            // 微信支付配置
            $wechatPayConf = config('app.wechat_pay');
            // 支付平台分配给开发者的应用ID
            $params->appID = $wechatPayConf['mini_appid'];
            // 微信支付分配的商户号
            $params->mch_id = $wechatPayConf['mch_id'];
            // 商户API 密钥
            $params->key = $wechatPayConf['mch_secret'];
            // SDK实例化，传入公共配置
            $pay = new SDK($params);
            // 支付接口（生成支付订单）
            $request = new Request();
            $request->body = $content;
            $request->out_trade_no = $paymentSn;
            // 支付金额 换算成: xx分
            $request->total_fee = $amount * 100;
            // $request->spbill_create_ip = '127.0.0.1';
            $request->notify_url = env('app.domain', 'https://docs.spacetimesc.com/').'v3/index/recvNotify';
            $request->openid = $openid;

            // 调用接口
            $result = $pay->execute($request);
            if ($pay->checkResult()) {
                $request = new jsRequest();
                $request->prepay_id = $result['prepay_id'];
                $jsapiParams = $pay->execute($request);
                // 增加本次发起支付的订单编号
                $insertData = [
                    'user_phone' => $reqParams['user_phone'],
                    'order_sn' => $paymentSn,
                    // 'combo_type' => $comboType,
                    'combo_type' => $tempTblComboType,
                    'order_amount' => $amount,
                    'add_time' => date('Y-m-d H:i:s', time()),
                ];
                $insertRes = Db::name('zifei_order')->insert($insertData);

                if (!$insertRes) {
                    throw new Exception('支付系统繁忙,请稍后再试!');
                }
                $res['code'] = 0;
                $res['data'] = $jsapiParams;

                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            } else {
                $res['msg'] = '微信支付,请求失败!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
        } catch (Exception $e) {
            $res['msg'] = $e->getMessage();
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * v3: 入单接口--得带上当前, 咨询类型.
     */
    public function intoOrder()
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];
        try {
            $reqParams = input('');

            // 入单请求参数
            // if (empty($reqParams['user_phone'])) {
            //     $res['msg'] = '用户唯一凭证为必传标识';
            //     exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            // }

            $comboType = isset($reqParams['combo_type']) ? $reqParams['combo_type'] : -1;
            $types = isset($reqParams['type']) ? $reqParams['type'] : -1;

            // 咨询类型. 总共分4个类型. TODO: 可使用数据库 管理[1, 2, 3, 4, 5, 6];
            $allowTypes = array_keys(config('app.mini_combo'));

            if (!in_array($types, $allowTypes)) {
                $res['msg'] = '咨询类型为必传!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 套餐类型: 0-单次咨询,1-包月套餐
            $comboTypeArr = [0, 1];

            if (!in_array($comboType, $comboTypeArr)) {
                $res['msg'] = '套餐标识错误';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 获取当前类型下, 每个套餐的数据表信息
            $miniComboConf = config('app.mini_combo');
            $tempTblComboType = $miniComboConf[$types][$comboType];

            if (empty($tempTblComboType)) {
                $res['msg'] = '套餐匹配失败!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 获取用户openid
            $mField = 'openid,once_nums,month_day,works_once_nums,works_month_nums,emotion_once_nums,emotion_month_nums,pr_once_nums,pr_month_nums,group_once_nums,group_month_nums,stu_once_nums,stu_month_nums';
            $memInfo = Db::name('member')->field($mField)->where(['phone' => $reqParams['user_phone']])->find();
            $openid = isset($memInfo['openid']) ? $memInfo['openid'] : '';

            if (empty($openid)) {
                $res['msg'] = '微信用户标识错误';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 当前用户有 包月套餐, 不允许购买单次套餐(月卡未过期之前不允许购买)
            // 根据用户的 咨询类型. 获取是否有咨询次数
            if ($types == 1 && $memInfo['month_day'] >= 1) {
                $res['msg'] = '当前已有包月套餐!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            if ($types == 2 && $memInfo['works_month_nums'] >= 1) {
                $res['msg'] = '当前已有包月套餐!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            if ($types == 3 && $memInfo['emotion_month_nums'] >= 1) {
                $res['msg'] = '当前已有包月套餐!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            if ($types == 4 && $memInfo['pr_month_nums'] >= 1) {
                $res['msg'] = '当前已有包月套餐!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            if ($types == 5 && $memInfo['group_month_nums'] >= 1) {
                $res['msg'] = '当前已有包月套餐!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            if ($types == 6 && $memInfo['stu_month_nums'] >= 1) {
                $res['msg'] = '当前已有包月套餐!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            // 根据套餐 类型获取支付金额
            $comboVal = Db::name('combos')->where(['combo_type' => $tempTblComboType])->column('fee');
            // TODO
            if (!isset($comboVal[0]) || $comboVal[0] <= 0) {
                $res['msg'] = '套餐资费配置错误';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }

            $amount = $comboVal[0];
            $content = '天纪云-咨询服务费';
            $paymentSn = 'AI_'.date('YmdHis').'_'.mt_rand(10000, 99999);

            $params = new PublicParams();
            // 微信支付配置
            $wechatPayConf = config('app.wechat_pay');
            // 支付平台分配给开发者的应用ID
            $params->appID = $wechatPayConf['mini_appid'];
            // 微信支付分配的商户号
            $params->mch_id = $wechatPayConf['mch_id'];
            // 商户API 密钥
            $params->key = $wechatPayConf['mch_secret'];
            // SDK实例化，传入公共配置
            $pay = new SDK($params);
            // 支付接口（生成支付订单）
            $request = new Request();
            $request->body = $content;
            $request->out_trade_no = $paymentSn;
            // 支付金额 换算成: xx分
            $request->total_fee = $amount * 100;
            // $request->spbill_create_ip = '127.0.0.1';
            $request->notify_url = env('app.domain', 'https://docs.spacetimesc.com/').'v3/index/recvNotify';
            $request->openid = $openid;

            // 调用接口
            $result = $pay->execute($request);
            if ($pay->checkResult()) {
                $request = new jsRequest();
                $request->prepay_id = $result['prepay_id'];
                $jsapiParams = $pay->execute($request);
                // 增加本次发起支付的订单编号
                $insertData = [
                    'user_phone' => $reqParams['user_phone'],
                    'order_sn' => $paymentSn,
                    // 'combo_type' => $comboType,
                    'combo_type' => $tempTblComboType,
                    'order_amount' => $amount,
                    'add_time' => date('Y-m-d H:i:s', time()),
                ];
                $insertRes = Db::name('zifei_order')->insert($insertData);

                if (!$insertRes) {
                    throw new Exception('支付系统繁忙,请稍后再试!');
                }
                $res['code'] = 0;
                $res['data'] = $jsapiParams;

                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            } else {
                $res['msg'] = '微信支付,请求失败!';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
        } catch (Exception $e) {
            $res['msg'] = $e->getMessage();
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * 回调接口.
     */
    public function recvNotify()
    {
        // 记录所有请求参数，包括GET和POST
        $allParams = input();
        Log::info('所有请求参数::'.json_encode(['data' => $allParams]));

        // 获取请求头的内容类型
        $contentType = request()->header('content-type');
        Log::info('请求内容类型::'.json_encode(['content-type' => $contentType]));

        // 尝试获取原始请求体
        $requestData = file_get_contents('php://input');

        // 检查是否有支付宝特有参数
        if (isset($allParams['app_id']) && isset($allParams['trade_status'])) {
            Log::info('识别为支付宝回调');
            $this->handleAlipayNotify($allParams);
        }
        // 检查是否是微信XML格式数据
        elseif (strpos($requestData, '<xml') !== false) {
            Log::info('识别为微信支付回调');
            $this->handleWechatNotify();
        }
        // 检查是否是PayPal回调
        elseif (isset($allParams['paypal_order_id']) || isset($allParams['order_id']) || isset($allParams['paymentToken'])) {
            Log::info('识别为PayPal回调');
            $this->handlePayPalNotify($allParams);
        } else {
            Log::info('无法识别的支付回调格式，参数:', json_encode(['params' => $allParams]));
            echo 'fail';
            exit;
        }
    }

    /**
     * 处理微信支付回调.
     */
    protected function handleWechatNotify()
    {
        $reqParams = file_get_contents('php://input');
        // Log::info('微信支付回调::'. $reqParams);
        // 解析通知的xml
        $xmlArr = parserXMLToArray($reqParams, 'array');
        // 本站订单号
        $orderSn = isset($xmlArr['out_trade_no']) ? $xmlArr['out_trade_no'] : '';
        $resultCode = isset($xmlArr['result_code']) ? $xmlArr['result_code'] : '';
        $transactionId = isset($xmlArr['transaction_id']) ? $xmlArr['transaction_id'] : '';

        if ($resultCode == 'SUCCESS') {
            // 更新订单信息
            $updateData = [
                'pay_time' => date('Y-m-d H:i:s', time()),
                'pay_status' => 1,
                'transaction_sn' => $transactionId,
                'pay_type' => 'wechat', // 标记为微信支付
            ];

            $this->updateOrderAndUserCombo($orderSn, $updateData);
        }

        echo 'success';
        exit;
    }

    /**
     * 处理支付宝回调.
     */
    protected function handleAlipayNotify($data)
    {
        // 支付成功，更新订单信息
        $updateData = [
            'pay_time' => date('Y-m-d H:i:s', time()),
            'pay_status' => 1,
            'transaction_sn' => $data['trade_no'],
            'pay_type' => 'alipay', // 标记为支付宝支付
        ];

        $this->updateOrderAndUserCombo($data['out_trade_no'], $updateData);

        echo 'success';
        exit;
    }

    /**
     * 处理PayPal回调.
     */
    protected function handlePayPalNotify($data)
    {
        try {
            $paypalOrderId = $data['order_id'] ?? $data['paypal_order_id'] ?? '';
            $orderSn = $data['order_sn'] ?? '';

            if (empty($paypalOrderId) || empty($orderSn)) {
                Log::error('PayPal回调参数不完整', $data);
                echo 'fail';
                exit;
            }

            // 验证PayPal订单状态
            $paypalService = new \app\service\PayPalService();
            $orderDetails = $paypalService->getOrderDetails($paypalOrderId);

            if ($orderDetails && isset($orderDetails['status']) && $orderDetails['status'] === 'COMPLETED') {
                // 支付成功，更新订单信息
                $updateData = [
                    'pay_time' => date('Y-m-d H:i:s', time()),
                    'pay_status' => 1,
                    'transaction_sn' => $paypalOrderId,
                    'pay_type' => 'paypal', // 标记为PayPal支付
                ];

                $this->updateOrderAndUserCombo($orderSn, $updateData);
                
                Log::info('PayPal支付成功处理完成', [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId
                ]);

                echo 'success';
            } else {
                Log::error('PayPal订单状态验证失败', [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId,
                    'status' => $orderDetails['status'] ?? 'unknown'
                ]);
                echo 'fail';
            }
        } catch (\Exception $e) {
            Log::error('PayPal回调处理异常', [
                'error' => $e->getMessage(),
                'data' => $data
            ]);
            echo 'fail';
        }
        exit;
    }

    /**
     * 处理支付宝支付.
     *
     * @param array  $reqParams 请求参数
     * @param string $paymentSn 支付订单号
     * @param float  $amount    支付金额
     * @param int    $comboType 套餐类型
     *
     * @return string
     */
    protected function doAlipayPayment($reqParams, $paymentSn, $amount, $comboType)
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];

        try {
            // 创建支付宝服务实例
            $aliPayService = new \app\service\AliPayService();

            // 判断是PC端还是移动端
            $isMobile = isset($reqParams['is_mobile']) ? (bool) $reqParams['is_mobile'] : false;

            // 获取套餐信息
            $comboInfo = Db::name('ai_combos')->field('name')->where(['id' => $comboType])->find();
            $subject = isset($comboInfo['name']) ? $comboInfo['name'] : '套餐购买';

            // 增加本次发起支付的订单记录
            $insertData = [
                'user_phone' => $reqParams['user_phone'],
                'order_sn' => $paymentSn,
                'combo_type' => $comboType,
                'order_amount' => $amount,
                'add_time' => date('Y-m-d H:i:s', time()),
                'pay_type' => 'alipay', // 标记为支付宝支付
            ];
            $insertRes = Db::name('zifei_order')->insert($insertData);

            if (!$insertRes) {
                throw new Exception('支付系统繁忙,请稍后再试!');
            }

            // 根据设备类型选择支付方式
            if ($isMobile) {
                // 手机网站支付
                $payResult = $aliPayService->wapPay($paymentSn, $subject, $amount);
            } else {
                // 电脑网站支付
                $payResult = $aliPayService->pagePay($paymentSn, $subject, $amount);
            }

            $res['code'] = 0;
            $res['data'] = [
                'pay_type' => 'alipay',
                'html' => $payResult, // 支付宝返回的表单HTML
                'order_sn' => $paymentSn,
            ];

            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        } catch (Exception $e) {
            $res['msg'] = $e->getMessage();
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * 解决方案支付接口.
     */
    public function resolveOrder()
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];
        try {
            $reqParams = input('');
            //1 解决方案  2 预测时间
            $type = $reqParams['type'];
            // 入单请求参数
            if (empty($reqParams['user_phone'])) {
                $res['msg'] = '用户唯一凭证为必传标识';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            //查询问题是否存在
            $itemId = Db::name('new_user_question_history')->where(['id' => $reqParams['history_id']])->value('person_menu_item_id');
            if (empty($itemId)) {
                $res['msg'] = '非法请求';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            //查询属于个人还是团体 结果 1 =>个人  2 => 团体
            $cid = Db::name('question_new')->where(['id' => $itemId])->value('cid1');
            //查询价格 个人id 11 个人解决方案 12 团体解决方案 13 个人预测时间 14 团队预测时间
            $cid += 10;
            if ($type == 2) {
                $cid += $type;
            }
            //解决方案 个人 11 团体12  预测时间 个人 13 团体14
            $comboVal = Db::name('combos')->where(['id' => $cid])->value('fee');

            if (!$comboVal) {
                $res['msg'] = '套餐资费配置错误';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            //获取用户openid
            $memInfo = Db::name('member')->field('openid')->where(['phone' => $reqParams['user_phone']])->find();
            $openid = isset($memInfo['openid']) ? $memInfo['openid'] : '';

            $amount = $comboVal;
            $content = '天纪云-咨询服务费';
            $paymentSn = 'AI_'.date('YmdHis').'_'.mt_rand(10000, 99999);

            $params = new PublicParams();
            // 微信支付配置
            $wechatPayConf = config('app.wechat_pay');
            // 支付平台分配给开发者的应用ID
            $params->appID = $wechatPayConf['mini_appid'];
            // 微信支付分配的商户号
            $params->mch_id = $wechatPayConf['mch_id'];
            // 商户API 密钥
            $params->key = $wechatPayConf['mch_secret'];
            // SDK实例化，传入公共配置
            $pay = new SDK($params);
            // 支付接口（生成支付订单）
            $request = new Request();
            $request->body = $content;
            $request->out_trade_no = $paymentSn;
            // 支付金额 换算成: xx分
            $request->total_fee = $amount * 100;
            // $request->spbill_create_ip = '127.0.0.1';
            $request->notify_url = env('app.domain', 'https://docs.spacetimesc.com/').'v3/index/resolveNotify';
            $request->openid = $openid;

            // 调用接口
            $result = $pay->execute($request);
            if ($pay->checkResult()) {
                $request = new jsRequest();
                $request->prepay_id = $result['prepay_id'];
                $jsapiParams = $pay->execute($request);
                // 增加本次发起支付的订单编号
                $insertData = [
                    'user_phone' => $reqParams['user_phone'],
                    'order_sn' => $paymentSn,
                    // 'combo_type' => $comboType,
                    'combo_type' => $cid,
                    'order_amount' => $amount,
                    'add_time' => date('Y-m-d H:i:s', time()),
                    'question_id' => $reqParams['history_id'],
                ];
                $insertRes = Db::name('zifei_order')->insert($insertData);

                if (!$insertRes) {
                    throw new Exception('支付系统繁忙,请稍后再试!');
                }
                $res['code'] = 0;
                $res['data'] = $jsapiParams;
            } else {
                $res['msg'] = '微信支付,请求失败!';
            }
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        } catch (Exception $e) {
            $res['msg'] = $e->getMessage();
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * 查询订单支付状态
     * v6/combo/checkOrderStatus.
     *
     * @return \think\response\Json
     */
    public function checkOrderStatus()
    {
        $orderSn = input('get.order_sn', '');

        if (empty($orderSn)) {
            return json(['code' => 1, 'msg' => '订单编号不能为空']);
        }

        try {
            // 查询订单状态
            $orderInfo = Db::name('zifei_order')
            ->where('out_trade_no', $orderSn)
            ->field('id, out_trade_no, pay_status, pay_time, transaction_sn, pay_amount, combo_type')
            ->find();

            if (empty($orderInfo)) {
                return json(['code' => 1, 'msg' => '订单不存在']);
            }

            return json(['code' => 0, 'msg' => '查询成功', 'data' => $orderInfo]);
        } catch (\Exception $e) {
            Log::write('查询订单支付状态失败：'.$e->getMessage(), 'error');

            return json(['code' => 1, 'msg' => '查询订单支付状态失败']);
        }
    }

    /**
     * 支付回调处理
     * 处理微信支付成功后的回调通知.
     */

    /**
     * 支付回调处理
     * 处理微信支付和支付宝支付成功后的回调通知.
     *
     * @return void
     */
    public function resolveNotify()
    {
        // 记录所有请求参数，包括GET和POST
        $allParams = input();
        Log::info('所有请求参数::'.json_encode(['data' => $allParams]));

        // 获取请求头的内容类型
        $contentType = request()->header('content-type');
        Log::info('请求内容类型::'.json_encode(['content-type' => $contentType]));

        // 尝试获取原始请求体
        $requestData = file_get_contents('php://input');

        // 检查是否有支付宝特有参数
        if (isset($allParams['app_id']) && isset($allParams['trade_status'])) {
            Log::info('识别为支付宝回调');
            $this->handleAlipayNotify($allParams);
        }
        // 检查是否是微信XML格式数据
        elseif (strpos($requestData, '<xml') !== false) {
            Log::info('识别为微信支付回调');
            $this->handleWechatNotify();
        }
        // 检查是否是PayPal回调
        elseif (isset($allParams['paypal_order_id']) || isset($allParams['order_id'])) {
            Log::info('识别为PayPal回调');
            $this->handlePayPalNotify($allParams);
        } else {
            Log::info('无法识别的支付回调格式，参数:', json_encode(['params' => $allParams]));
            echo 'fail';
            exit;
        }
    }

    /**
     * 更新订单状态和用户套餐信息.
     *
     * @param string $orderSn    订单号
     * @param array  $updateData 更新数据
     *
     * @return void
     */
    protected function updateOrderAndUserCombo($orderSn, $updateData)
    {
        //查询订单是否存在
        $zfOrder = Db::name('zifei_order')->field('combo_type_str,question_id,user_phone')->where(['order_sn' => $orderSn, 'pay_status' => 0])->find();
        if ($zfOrder) {
            Db::startTrans();
            try {
                // 更新订单状态
                $orderRes = Db::name('zifei_order')->where(['order_sn' => $orderSn, 'pay_status' => 0])->update($updateData);

                // 如果是套餐付费，则更新用户套餐信息
                $comboType = $zfOrder['combo_type_str'];
                $userId = $zfOrder['user_phone'];  //这里的user_phone就是用户的id
                $package_type = strtolower($comboType); // 转小写便于判断

                if (!empty($userId)) {
                    // 查询用户信息
                    $userInfo = Db::name('member')->where('id', $userId)->find();
                    if ($userInfo) {
                        $updateUserData = [];

                        // 根据套餐类型更新用户套餐信息
                        if (strpos($package_type, 'month') !== false) {
                            // 如果包含"month"，则为月卡，需要更新时间

                            $field = $package_type;
                            if (isset($field)) {
                                $currentTime = time();
                                $endTime = $userInfo[$field] ?? 0;

                                // 如果已过期，则从当前时间开始算起延期30天
                                // 如果未过期，则在原有到期时间基础上延期30天
                                if ($endTime < $currentTime) {
                                    $newEndTime = $currentTime + (30 * 24 * 3600); // 当前时间+30天
                                } else {
                                    $newEndTime = $endTime + (30 * 24 * 3600); // 原到期时间+30天
                                }

                                $updateUserData[$field] = $newEndTime;
                            }
                        } elseif (strpos($package_type, 'once') !== false) {
                            // 如果包含"once"，则为次卡，需要增加次数
                            $field = $package_type;

                            // if (isset($field)) {
                            //     // 次数+1
                            //     $updateUserData[$field] = ['exp', $field.'+1'];
                            // }
                        }

                        // 更新用户套餐信息
                        if (!empty($updateUserData)) {
                            Db::name('member')->where('id', $userId)->update($updateUserData);
                        } elseif (isset($field)) {
                            // 对于次数类套餐，增加次数
                            Db::name('member')->where('id', $userId)->setInc($field);
                        }
                    }
                }
                Db::commit();
                Log::info('订单支付成功处理完成::'.json_encode(['order_sn' => $orderSn]));
            } catch (\Exception $e) {
                Db::rollback();
                Log::info('回调处理异常::'.json_encode(['error' => $e->getMessage()]));
            }
        } else {
            Log::info('未查询到订单详情::'.json_encode(['order_sn' => $orderSn]));
        }
    }

    /**
     * 支付下单返回支付二维码
     * 实现Native支付，参考文档：https://pay.weixin.qq.com/doc/v3/merchant/4012791877.
     */
    public function recharge()
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];
        $userId = getUserId();
        if (empty($userId)) {
            $res['code'] = 401;
            $res['msg'] = '请先登录';
            exit(json_encode($res, JSON_UNESCAPED_UNICODE));
        }
        try {
            $combo_type = input('combo_type', 0); //套餐类型
            $amount = input('amount', 0); //金额
            // $amount = 0.01;
            $device_type = input('device_type', ''); // 设备类型，可以是 'pc' 或 'mobile'
            $return_url = input('return_url', ''); // 返回url
            //获取支付类型
            $pay_type = input('pay_type', '');

            if (empty($combo_type)) {
                $res['msg'] = '套餐类型为必传标识';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }
            if (empty($amount) || $amount <= 0) {
                $res['msg'] = '金额不能为空或小于等于0';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }

            // 获取用户信息
            $userInfo = Db::name('member')->where('id', $userId)->find();
            if (empty($userInfo)) {
                $res['msg'] = '未找到用户信息';
                exit(json_encode($res, JSON_UNESCAPED_UNICODE));
            }

            // 创建订单号
            $content = '天纪云-套餐付费';
            $paymentSn = 'AI_'.date('YmdHis').'_'.mt_rand(10000, 99999);

            // 判断设备类型
            $is_mobile = false;

            // 如果前端没有传递设备类型，则自动判断
            if (empty($device_type)) {
                $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
                // 检查是否是移动设备
                if (preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i', $user_agent) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', substr($user_agent, 0, 4))) {
                    $is_mobile = true;
                }
            } else {
                // 使用前端传递的设备类型
                $is_mobile = ($device_type == 'mobile');
            }

            // 首先记录订单信息到数据库
            $insertData = [
                'user_phone' => $userId,
                'order_sn' => $paymentSn,
                'combo_type' => 0, // 保存前端传入的包类型
                'combo_type_str' => $combo_type,
                'order_amount' => $amount,
                'add_time' => date('Y-m-d H:i:s', time()),
                'return_url' => $return_url ?? '',
            ];
            $insertRes = Db::name('zifei_order')->insert($insertData);

            if (!$insertRes) {
                throw new Exception('支付系统繁忙,请稍后再试!');
            }

            if ($pay_type == 'paypal') {
                // PayPal支付处理
                try {
                    $paypalService = new \app\service\PayPalService();
                    
                    // 创建PayPal订单
                    $paypalOrder = $paypalService->createOrder($paymentSn, $content, $amount);
                    
                    if ($paypalOrder && isset($paypalOrder['id'])) {
                        $res['code'] = 0;
                        $res['data'] = [
                            'type' => 'paypal',
                            'paypal_order_id' => $paypalOrder['id'],
                            'order_sn' => $paymentSn,
                        ];
                        
                        // 更新订单记录PayPal订单ID
                        Db::name('zifei_order')->where(['order_sn' => $paymentSn])->update([
                            'payment_method' => 'PAYPAL',
                            'paypal_order_id' => $paypalOrder['id']
                        ]);
                        
                        Log::info('PayPal订单创建成功', [
                            'order_sn' => $paymentSn,
                            'paypal_order_id' => $paypalOrder['id']
                        ]);
                    } else {
                        $res['code'] = 1;
                        $res['msg'] = 'PayPal订单创建失败';
                        Log::error('PayPal订单创建失败', ['order_sn' => $paymentSn]);
                    }
                } catch (\Exception $e) {
                    $res['code'] = 1;
                    $res['msg'] = 'PayPal支付创建异常: ' . $e->getMessage();
                    Log::error('PayPal支付异常', ['message' => $e->getMessage()]);
                }
            } elseif ($pay_type == 'wechat') {
                try {
                    // 检查是否为微信浏览器
                    $userAgent = request()->header('user-agent');
                    $isWechatBrowser = strpos($userAgent, 'MicroMessenger') !== false;
                    
                    // 只在微信浏览器中支持支付
                    if (!$isWechatBrowser) {
                        $res['code'] = 1;
                        $res['msg'] = '微信支付仅支持在微信浏览器中使用';
                        return json($res);
                    }
                    
                    // 微信支付配置
                    $wechatPayConf = config('app.wechat_pay');

                    // 创建公共参数
                    $params = new PublicParams();
                    // 支付平台分配给开发者的应用ID
                    $params->appID = 'wxb05325fedb08c337';
                    // 微信支付分配的商户号
                    $params->mch_id = $wechatPayConf['mch_id'];
                    // 商户API 密钥
                    $params->key = $wechatPayConf['mch_secret'];

                    // SDK实例化，传入公共配置
                    $pay = new SDK($params);

                    // 支付接口
                    $request = new Request();
                    $request->body = $content; // 商品描述
                    $request->out_trade_no = $paymentSn; // 订单号
                    $request->total_fee = intval($amount * 100); // 订单总金额，单位为：分
                    // $request->spbill_create_ip = request()->ip(); // 客户端ip
                    $request->notify_url = env('app.domain', 'https://docs.spacetimesc.com/').'/v6/combo/recvNotify'; // 异步通知地址
                    $request->attach = 'package_type:'.$combo_type; // 附加数据
                    $request->openid = $userInfo['openid'];
                    // 记录调试日志
                    Log::info('微信H5支付请求参数::'.json_encode([
                        'body' => $request->body,
                        'out_trade_no' => $request->out_trade_no,
                        'total_fee' => $request->total_fee,
                        'spbill_create_ip' => $request->spbill_create_ip,
                        'notify_url' => $request->notify_url,
                        'attach' => $request->attach,
                    ]));

                    // 调用接口
                    $result = $pay->execute($request);
                    Log::info('微信H5支付响应数据::'.json_encode($result));

                    if ($pay->checkResult()) {
                        $res['code'] = 0;
                        $request = new jsRequest();
                        $request->prepay_id = $result['prepay_id'];
                        $jsapiParams = $pay->execute($request);
                        $res['data'] = $jsapiParams;
                    } else {
                        $res['code'] = 1;
                        $res['msg'] = $pay->getErrorCode().':'.$pay->getError();
                        Log::error('微信H5支付错误::'.$res['msg']);
                    }
                } catch (\Exception $e) {
                    $res['code'] = 1;
                    $res['msg'] = '微信支付创建异常: '.$e->getMessage();
                    Log::error('微信支付异常::'.json_encode(['message' => $e->getMessage()]));
                }

                // 微信支付返回数据
                Db::name('zifei_order')->where(['order_sn' => $paymentSn])->update(['payment_method' => $is_mobile ? 'WECHAT_H5' : 'WECHAT_NATIVE']);

                // 记录调试日志
                Log::info('微信支付参数生成成功', [
                    'payment_method' => $is_mobile ? 'WECHAT_H5' : 'WECHAT_NATIVE',
                    'order_sn' => $paymentSn,
                    'is_mobile' => $is_mobile,
                    'device_type' => $device_type,
                ]);
            } else {
                // 实例化支付宝支付服务
                $alipayService = new \app\service\AliPayService();

                if ($is_mobile) {
                    $paymentMethod = 'ALIPAY_WAP';
                    // 手机网站支付
                    $payForm = $alipayService->wapPay(
                        $paymentSn,
                        $content,
                        $amount,
                        'package_type:'.$combo_type
                    );
                    $res['code'] = 0;
                    $res['data'] = [
                        'type' => 'alipay_wap',
                        'form' => $payForm,
                        'out_trade_no' => $paymentSn,
                    ];
                } else {
                    $paymentMethod = 'ALIPAY_PAGE';
                    // 电脑网站支付
                    $payForm = $alipayService->pagePay(
                        $paymentSn,
                        $content,
                        $amount,
                        'package_type:'.$combo_type
                    );
                    $res['code'] = 0;
                    $res['data'] = [
                        'type' => 'alipay_page',
                        'form' => $payForm,
                        'out_trade_no' => $paymentSn,
                    ];
                }

                // 支付宝支付返回数据
                Db::name('zifei_order')->where(['order_sn' => $paymentSn])->update(['payment_method' => $paymentMethod]);

                // 记录调试日志
                Log::info(Lang::get('alipay_params_generate_success').json_encode([
                    'payment_method' => $paymentMethod,
                    'order_sn' => $paymentSn,
                    'is_mobile' => $is_mobile,
                    'device_type' => $device_type,
                ]));
            }

            // 返回最终结果
        } catch (Exception $e) {
            $res['msg'] = $e->getMessage();
            Log::error(Lang::get('alipay_order_failed'), ['error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
        }

        exit(json_encode($res, JSON_UNESCAPED_UNICODE));
    }

    /**
     * PayPal订单捕获接口
     * 用户完成PayPal授权后调用此接口捕获支付
     */
    public function paypalCapture()
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];
        
        try {
            $params = input('');
            $paypalOrderId = $params['order_id'] ?? '';
            $orderSn = $params['order_sn'] ?? '';

            if (empty($paypalOrderId) || empty($orderSn)) {
                $res['msg'] = '参数不完整';
                return json($res);
            }

            // 验证本地订单是否存在
            $localOrder = Db::name('zifei_order')
                ->where(['order_sn' => $orderSn, 'pay_status' => 0])
                ->find();

            if (empty($localOrder)) {
                $res['msg'] = '订单不存在或已处理';
                return json($res);
            }

            // 捕获PayPal订单
            $paypalService = new \app\service\PayPalService();
            $captureResult = $paypalService->captureOrder($paypalOrderId);

            if ($captureResult && isset($captureResult['status']) && $captureResult['status'] === 'COMPLETED') {
                // 支付成功，更新订单信息
                $updateData = [
                    'pay_time' => date('Y-m-d H:i:s', time()),
                    'pay_status' => 1,
                    'transaction_sn' => $paypalOrderId,
                    'pay_type' => 'paypal',
                ];

                $this->updateOrderAndUserCombo($orderSn, $updateData);
                //处理payPal订单
                $this->paypalCallback($updateData);
                $res['code'] = 0;
                $res['msg'] = 'PayPal支付成功';
                $res['data'] = [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId,
                    'pay_status' => 1
                ];
                
                Log::info('PayPal支付捕获成功', [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId,
                    'capture_result' => $captureResult
                ]);
            } else {
                $res['msg'] = 'PayPal支付捕获失败';
                Log::error('PayPal支付捕获失败', [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId,
                    'capture_result' => $captureResult
                ]);
            }
        } catch (\Exception $e) {
            $res['msg'] = 'PayPal支付捕获异常: ' . $e->getMessage();
            Log::error('PayPal支付捕获异常', [
                'error' => $e->getMessage()
            ]);
        }

        return json($res);
    }

    /**
     * PayPal支付回调接口
     * 前端调用此接口验证PayPal支付结果
     */
    public function paypalCallback()
    {
        $res = ['code' => 1, 'data' => [], 'msg' => ''];
        
        try {
            $params = input('');
            $paypalOrderId = $params['order_id'] ?? '';
            $orderSn = $params['order_sn'] ?? '';

            if (empty($paypalOrderId) || empty($orderSn)) {
                $res['msg'] = '参数不完整';
                return json($res);
            }

            // 验证PayPal订单状态
            $paypalService = new \app\service\PayPalService();
            $orderDetails = $paypalService->getOrderDetails($paypalOrderId);

            if ($orderDetails && isset($orderDetails['status']) && $orderDetails['status'] === 'COMPLETED') {
                // 支付成功，更新订单信息
                $updateData = [
                    'pay_time' => date('Y-m-d H:i:s', time()),
                    'pay_status' => 1,
                    'transaction_sn' => $paypalOrderId,
                    'pay_type' => 'paypal',
                ];

                $this->updateOrderAndUserCombo($orderSn, $updateData);
                
                $res['code'] = 0;
                $res['msg'] = 'PayPal支付验证成功';
                $res['data'] = [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId,
                    'pay_status' => 1
                ];
                
                Log::info('PayPal支付验证成功', [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId
                ]);
            } else {
                $res['msg'] = 'PayPal支付验证失败';
                Log::error('PayPal支付验证失败', [
                    'order_sn' => $orderSn,
                    'paypal_order_id' => $paypalOrderId,
                    'status' => $orderDetails['status'] ?? 'unknown'
                ]);
            }
        } catch (\Exception $e) {
            $res['msg'] = 'PayPal支付验证异常: ' . $e->getMessage();
            Log::error('PayPal支付验证异常', [
                'error' => $e->getMessage()
            ]);
        }

        return json($res);
    }
}
